import psutil
import socket
import subprocess
import openpyxl
import re
import sys
import serial
import requests
import time

def test_check_ethernet_addresses(imei):
    # 获取所有网络接口的信息
    addrs = psutil.net_if_addrs()
    stats = psutil.net_if_stats()

    found_ip = False
    target_host = 'www.baidu.com'    
    for interface, addresses in addrs.items():
        if "以太网" in interface and stats[interface].isup:
            print(f"******检测到以太网适配器: {interface}******")       
            for addr in addresses:
                if addr.family == socket.AF_INET:  # IPv4
                    print(f"  IPv4 地址: {addr.address}")
                    found_ip = True
                    # 检查网络连接
                    if ping_host(target_host):
                        print("网络连接成功")
                        # 更新Excel文件中的状态
                        update_excel_status('Ethernet', 'Pass',imei,'record.xlsx')
                    else:
                        print("网络连接失败")
                        # 更新Excel文件中的状态
                        update_excel_status('Ethernet', 'Fail',imei, 'record.xlsx')
    if not found_ip:
        print("******未找到以太网适配器******")

def ping_host(host):
    # Windows下使用ping命令，默认IPv4地址
    ping_cmd = ['ping', '-n', '4','-4', host]
    
    try:
        result = subprocess.run(ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=10)
        print(result.stdout)
        lost_packets = 999
        for line in result.stdout.split('\n'):
            if '丢失 = ' in line:
                # 使用正则表达式提取丢失的数字
                lost_match = re.search(r"丢失 = (\d+)", line)
                # 如果找到匹配项，提取数字
                if lost_match:
                    lost_packets = int(lost_match.group(1))
                    print(f"丢失的数据包数量: {lost_packets}")
                else:
                    print("未找到丢失的数据包数量")
                break                    
        if lost_packets == 0:
            return True
        else:
            return False
    except Exception as e:
        print(f"ping命令执行出错: {e}")
        return False

# 更新Excel文件的函数
def update_excel_status(test_name, result, imei, filename='record.xlsx'):
    try:
        # 加载现有工作簿
        workbook = openpyxl.load_workbook(filename)
        sheet = workbook.active

        # 寻找 test_name 和 imei 所在的列和行
        test_name_column = None
        imei_row = None
        for column in range(1, sheet.max_column + 1):
            if sheet.cell(row=1, column=column).value == test_name:
                test_name_column = column
                break

        for row in range(2, sheet.max_row + 1):
            if sheet.cell(row=row, column=1).value == imei:
                imei_row = row
                break

        # 如果找到了对应的列和行，则写入结果
        if test_name_column and imei_row:
            sheet.cell(row=imei_row, column=test_name_column, value=result)
            workbook.save(filename)
            print(f"数据 {result} 已写入 {filename} 文件的 {test_name} 列，{imei} 行。")
        else:
            print(f"未找到 {test_name} 列或 {imei} 行。")

    except FileNotFoundError:
        print(f"{filename} 文件未找到。")

def get_imei_from_device(port, baudrate):
    # 尝试打开串口
    try:
        ser = serial.Serial(port=port, baudrate=baudrate, timeout=1)
    except serial.SerialException as e:
        print(f"串口{port}无法打开: {e}")
        sys.exit(1)
       
    # 发送命令获取IMEI
    ser.write(b'AT+CGSN\r\n')
    response = ser.readlines()
    imei = response[-3].decode('utf-8').strip()  # 通常IMEI号在响应的倒数第三行
    ser.close()  # 关闭串口
    return imei

def write_imei_to_excel(imei, filename='record.xlsx'):
    try:
        # 加载现有工作簿
        workbook = openpyxl.load_workbook(filename)
        sheet = workbook.active

        # 寻找 IMEI 列
        imei_column = None
        for column in range(1, sheet.max_column + 1):
            if sheet.cell(row=1, column=column).value == 'IMEI':
                imei_column = column
                break

        # 如果找到了 IMEI 列，则写入 IMEI 号
        if imei_column:
            # 检查 IMEI 是否已存在于列中
            imei_exists = False
            for row in range(2, sheet.max_row + 1):  # 从第二行开始检查
                if sheet.cell(row=row, column=imei_column).value == imei:
                    imei_exists = True
                    break

            # 如果 IMEI 不存在，则写入新的行
            if not imei_exists:
                new_row = sheet.max_row + 1
                sheet.cell(row=new_row, column=imei_column, value=imei)
                workbook.save(filename)
                print(f"IMEI号 {imei} 已写入 {filename} 文件的 IMEI 列。")
            else:
                print(f"IMEI号 {imei} 已存在于 {filename} 文件的 IMEI 列中，不重复写入。")            
        else:
            print("未找到 IMEI 列。")

    except FileNotFoundError:
        print(f"{filename} 文件未找到。")

def test_check_sim_card(port, baudrate,imei):
    try:
        # 打开串口
        ser = serial.Serial(port, baudrate, timeout=1)
        # 成功打开串口，则USB项测试成功
        update_excel_status('USB', 'Pass',imei,'record.xlsx')
        # 发送命令检查SIM卡状态
        ser.write(b'AT+CPIN?\r\n')
        response = ser.readlines()
        
        # 检查响应中是否包含READY
        sim_status_line = response[-3].decode('utf-8').strip()
        print(sim_status_line)
         # 判断该行是否包含READY
        if "READY" in sim_status_line:
            print("SIM卡已就位")
            update_excel_status('SIM_Card', 'Pass',imei,'record.xlsx')
            ser.close()  # 关闭串口
        else:
            print("SIM卡未就位")
            update_excel_status('SIM_Card', 'Fail',imei,'record.xlsx')
            ser.close()  # 关闭串口
    except serial.SerialException as e:
        print(f"无法打开串口：{e}")
        update_excel_status('USB', 'Fail',imei,'record.xlsx')
        return False

def test_check_web(imei):
    try:
        # 尝试访问百度网页
        response = requests.get("http://www.baidu.com", timeout=5)
        # 如果响应状态码为200，表示成功
        if response.status_code == 200:
            print("成功访问百度网页")
            update_excel_status('Web', "Pass", imei, 'record.xlsx')
            return True
        else:
            print("访问百度网页失败")
            update_excel_status('Web', "Fail", imei, 'record.xlsx')
            return False
    except requests.RequestException as e:
        print(f"无法访问百度网页：{e}")
        update_excel_status('Web', "Fail", imei, 'record.xlsx')
        return False

def test_check_rest(imei):
    # 提示用户输入 'y' 来启动睡眠
    user_input = input("请输入 'y' 启动复位：")
    if user_input.lower() != 'y':
        print("用户未输入 'y'，退出程序。")
        return
    # 睡眠 1 分钟，每 10 秒打印一次进度
    for i in range(1, 13):
        time.sleep(5)
        print(f"正在复位... 已经过 {i*5}/60 秒")
    # 检查网络连接
    target_host = 'www.baidu.com'    
    if ping_host(target_host):
        print("网络连接成功")
        # 更新Excel文件中的状态
        update_excel_status('Reset', 'Pass',imei,'record.xlsx')
    else:
        print("网络连接失败")
        # 更新Excel文件中的状态
        update_excel_status('Reset', 'Fail',imei, 'record.xlsx')

def test_check_light(imei):
    # 提示用户输入 'y' 来确认红灯亮起
    user_input = input("请输入 'y' 确认红灯已经亮起：")
    if user_input.lower() != 'y':
        update_excel_status('Light', 'Fail', imei, 'record.xlsx')
        print("用户未输入 'y'，更新Excel状态为失败并退出程序。")
        return
    else:
        update_excel_status('Light', 'Pass', imei, 'record.xlsx')

    # 提示用户输入 'y' 来确认绿灯亮起
    user_input = input("请输入 'y' 确认绿灯已经亮起：")
    if user_input.lower() != 'y':
        update_excel_status('Light_NET', 'Fail', imei, 'record.xlsx')
        print("用户未输入 'y'，更新Excel状态为失败并退出程序。")
        return
    else:
        update_excel_status('Light_NET', 'Pass', imei, 'record.xlsx')

    # 睡眠 10 秒钟，每 5 秒打印一次进度
    for i in range(1, 3):
        time.sleep(5)
        print(f"正在等待入网... 已经过 {i*5}/10 秒")

# 新增的test_check_5g_state函数，用于检查5G网络状态
def test_check_5g_state(port, baudrate, imei):
    try:
        # 打开串口
        ser = serial.Serial(port, baudrate, timeout=1)

        # 下发命令 AT+C5GREG?
        command = "AT+C5GREG?\r\n"
        ser.write(command.encode())

        # 读取返回值
        response = ser.readline().decode().strip()
        print("串口返回值：", response)

        # 判断返回值
        if "+C5GREG: 0,1" in response:
            update_excel_status('5G', 'Pass', imei, 'record.xlsx')
            print("5G网络入网成功。")
        else:
            update_excel_status('5G', 'Fail', imei, 'record.xlsx')
            print("5G网络入网失败。")

        # 关闭串口
        ser.close()
        print("串口已关闭。")

    except serial.SerialException as e:
        print("打开串口失败：", e)
        update_excel_status('5G', 'Fail', imei, 'record.xlsx')

def main():
    if len(sys.argv) != 3:
        print("Usage: python script.py <port> <baudrate>")
        sys.exit(1)
    port = sys.argv[1]
    baudrate = int(sys.argv[2])
    
    imei = get_imei_from_device(port, baudrate)
    write_imei_to_excel(imei)
    #开始第一项测试，检测红灯和绿灯是否亮起
    test_check_light(imei)
    # 开始第二项测试，检测SIM卡是否就位
    test_check_sim_card(port, baudrate,imei)
    # 开始第三项测试，检测5G入网情况
    test_check_5g_state(port, baudrate,imei)        
    # 开始第四项测试，检测网卡是否获取IP，是否能ping通百度
    test_check_ethernet_addresses(imei)
    # 开始第五项测试，检测是否能浏览百度网址
    test_check_web(imei)
    # 最后一项测试，检测复位是否成功
    test_check_rest(imei)
if __name__ == "__main__":
    main()